home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 8 / QRZ Ham Radio Callsign Database - Volume 8.iso / pc / files / t_unix / j109lxa4.tar / mailcli.c < prev    next >
C/C++ Source or Header  |  1994-06-04  |  8KB  |  378 lines

  1. /* Mail Command Line Interface -- Clients
  2.  * Copyright 1992 William Allen Simpson
  3.  *      partly based on a MAIL client design by Anders Klemets, SM0RGV
  4.  *
  5.  * Mods by PA0GRI
  6.  * Improved param cracking
  7.  */
  8. #include <ctype.h>
  9. #include <stdio.h>
  10. #include <time.h>
  11. #include <string.h>
  12. #include "global.h"
  13. #include "timer.h"
  14. #include "proc.h"
  15. #include "socket.h"
  16. #include "domain.h"
  17. #include "cmdparse.h"
  18. #include "files.h"
  19. #include "netuser.h"
  20. #include "mailcli.h"
  21. #include "mailutil.h"
  22. #include "smtp.h"
  23.  
  24.  
  25. /* Tracing levels:
  26.     0 - no tracing
  27.     1 - serious errors reported
  28.     2 - transient errors reported
  29.     3 - session progress reported
  30.  */
  31. unsigned short Mailtrace = 1;
  32.  
  33. #ifdef MAILCLIENT
  34.  
  35. int Mailquiet = FALSE;
  36.  
  37. struct mailservers *Mailservers = NULLMAIL;
  38.  
  39. static int domsquiet __ARGS((int argc,char *argv[],void *p));
  40. static int domstrace __ARGS((int argc,char *argv[],void *p));
  41. static int doadds __ARGS((int argc,char *argv[],void *p));
  42. static int dodrops __ARGS((int argc,char *argv[],void *p));
  43. static int dokicks __ARGS((int argc,char *argv[],void *p));
  44. static int dolists __ARGS((int argc,char *argv[],void *p));
  45.  
  46. static void mailtick __ARGS((void *tp));
  47.  
  48. static char mreaderr[] = "popmail: Missing";
  49.  
  50. static struct cmds Mailcmds[] = {
  51.     "addserver",    doadds,         0, 2, "popmail addserver <mailserver>"
  52.             " [<seconds>] [hh:mm-hh:mm] <protocol>"
  53.             " <mailbox> <username> <password>",
  54.     "dropserver",   dodrops,        0, 2, "popmail dropserver <mailserver>",
  55.     "kick",         dokicks,        0, 2, "popmail kick <mailserver>",
  56.     "list",         dolists,        0, 0, NULLCHAR,
  57.     "quiet",        domsquiet,      0, 0, NULLCHAR,
  58.     "trace",        domstrace,      0, 0, NULLCHAR,
  59.     NULLCHAR,
  60. };
  61.  
  62.  
  63. int
  64. domsread(argc,argv,p)
  65. int argc;
  66. char *argv[];
  67. void *p;
  68. {
  69.     return subcmd(Mailcmds,argc,argv,p);
  70. }
  71.  
  72.  
  73. static int
  74. domsquiet(argc,argv,p)
  75. int argc;
  76. char *argv[];
  77. void *p;
  78. {
  79.     return setbool(&Mailquiet,"mail quiet",argc,argv);
  80. }
  81.  
  82. #endif
  83.  
  84. static int
  85. domstrace(argc, argv, p)
  86. int argc;
  87. char *argv[];
  88. void *p;
  89. {
  90.     return setshort(&Mailtrace,"mail tracing",argc,argv);
  91. }
  92.     
  93. #ifdef MAILCLIENT
  94.  
  95. static int
  96. doadds(argc,argv,p)
  97. int argc;
  98. char *argv[];
  99. void *p;
  100. {
  101.     struct mailservers *np;
  102.     char *fullname;
  103.     int i;
  104.     int32 addr;
  105.  
  106.     fullname = domainsuffix(argv[1]);
  107.     if((addr = resolve(fullname)) == 0L){
  108.     tprintf("Unknown host %s\n",fullname);
  109.     /* domainsuffix() ALLOCATED memory !, so free it - WG7J */
  110.     free(fullname);
  111.     return 1;
  112.     }
  113.  
  114.     i = 2;
  115.     np = (struct mailservers *) callocw(1,sizeof(struct mailservers));
  116.     np->hostname = fullname;
  117.     np->next = Mailservers;
  118.     Mailservers = np;
  119.     np->lowtime = np->hightime = -1;
  120.     np->timer.func = mailtick;  /* what to call on timeout */
  121.     np->timer.arg = (void *)np;
  122.  
  123.     if( argc > i && isdigit(*argv[i])){
  124.         if(strchr(argv[i],'-') == NULLCHAR ) 
  125.             /* set timer duration */
  126.             set_timer(&np->timer,atol(argv[i++])*1000L);
  127.     }
  128.  
  129.     if( argc > i && isdigit(*argv[i])){
  130.         int lh, ll, hh, hl;
  131.         sscanf(argv[i++], "%d:%d-%d:%d", &lh, &ll, &hh, &hl);
  132.         np->lowtime = lh * 100 + ll;
  133.         np->hightime = hh * 100 + hl;
  134.     }
  135.  
  136.     if ( argc > i ) {
  137.         struct daemon *dp = Mailreaders;
  138.  
  139.         for ( ; dp->name != NULLCHAR ; dp++ ) {
  140.             if ( stricmp(dp->name, argv[i]) == 0 ) {
  141.                 np->reader = dp;
  142.                 break;
  143.             }
  144.         }
  145.         if ( np->reader == NULLDAEMON ) {
  146.             tprintf("unrecognized protocol '%s'\n", argv[i] );
  147.             goto quit;
  148.         }
  149.         i++;
  150.     } else {
  151.         tprintf("%s protocol\n",mreaderr);
  152.         goto quit;
  153.     }
  154.  
  155.     if ( argc > i ) {
  156.         np->mailbox = strdup(argv[i++]);
  157.     } else {
  158.         tprintf("%s mailbox\n",mreaderr);
  159.         goto quit;
  160.     }
  161.  
  162.     if ( argc > i ) {
  163.         np->username = strdup(argv[i++]);
  164.     } else {
  165.         tprintf("%s username\n",mreaderr);
  166.         goto quit;
  167.     }
  168.  
  169.     if ( argc > i ) {
  170.         np->password = strdup(argv[i++]);
  171.     } else {
  172.         tprintf("%s password\n",mreaderr);
  173.         goto quit;
  174.     }
  175.  
  176.     start_timer(&np->timer);            /* and fire it up */
  177.     return 0;
  178.  
  179. quit:
  180.     Mailservers = np->next;
  181.     free(np->hostname);
  182.     free(np->username);
  183.     free(np->password);
  184.     free(np->mailbox);
  185.     free((char *)np);
  186.     return -1;
  187. }
  188.  
  189.  
  190. static int
  191. dodrops(argc,argv,p)
  192. int argc;
  193. char *argv[];
  194. void *p;
  195. {
  196.     struct mailservers *np, *npprev = NULLMAIL;
  197.     char *fullname;
  198.  
  199.     fullname = domainsuffix(argv[1]);
  200.     for (np = Mailservers; np != NULLMAIL; npprev = np, np = np->next) {
  201.         if(strnicmp(np->hostname,fullname,strlen(fullname)) == 0) {
  202.             stop_timer(&np->timer);
  203.             free(np->hostname);
  204.             free(np->username);
  205.             free(np->password);
  206.             free(np->mailbox);
  207.  
  208.             if(npprev != NULLMAIL)
  209.                 npprev->next = np->next;
  210.             else
  211.                 Mailservers = np->next;
  212.             free((char *)np);
  213.             return 0;
  214.         }
  215.     }
  216.     tprintf("No such server enabled.\n");
  217.     return -1;
  218. }
  219.  
  220.  
  221. static int
  222. dolists(argc,argv,p)
  223. int argc;
  224. char *argv[];
  225. void *p;
  226. {
  227.     struct mailservers *np;
  228.  
  229.     for (np = Mailservers; np != NULLMAIL; np = np->next) {
  230.         char tbuf[80];
  231.         if (np->lowtime != -1 && np->hightime != -1)
  232.             sprintf(tbuf, " %02d:%02d-%02d:%02d",
  233.                 np->lowtime/100,
  234.                 np->lowtime%100,
  235.                 np->hightime/100,
  236.                 np->hightime%100);
  237.         else
  238.             tbuf[0] = '\0';
  239.         tprintf("%-32s (%lu/%lu%s) %s %s\n",
  240.             np->hostname,
  241.             read_timer(&np->timer) /1000L,
  242.             dur_timer(&np->timer) /1000L,
  243.             tbuf,
  244.             np->reader->name,
  245.             np->username );
  246.     }
  247.     return 0;
  248. }
  249.  
  250.  
  251. static int
  252. dokicks(argc,argv,p)
  253. int argc;
  254. char *argv[];
  255. void *p;
  256. {
  257.     struct mailservers *np;
  258.     char *fullname;
  259.  
  260.     fullname = domainsuffix(argv[1]);
  261.     for (np = Mailservers; np != NULLMAIL; np = np->next) {
  262.         if(strnicmp(np->hostname,fullname,strlen(fullname)) == 0) {
  263. #ifndef UNIX
  264.             if(availmem() - np->reader->stksize < Memthresh){
  265.                 tprintf("insufficient memory\n");
  266.                 return 1;
  267.             }
  268. #endif
  269.             /* If the timer is not running, the timeout function
  270.              * has already been called, and we don't want to call
  271.              * it again.
  272.              */
  273.             if ( np->timer.duration == 0
  274.               || run_timer(&np->timer) ) {
  275.                 stop_timer(&np->timer);
  276.                 newproc( np->reader->name,
  277.                     np->reader->stksize,
  278.                     np->reader->fp,
  279.                     0, np, NULL,0);
  280.             }
  281.             return 0;
  282.         }
  283.     }
  284.     tprintf("No such server enabled.\n");
  285.     return -1;
  286. }
  287.  
  288.  
  289. static void
  290. mailtick(tp)
  291. void *tp;
  292. {
  293.     struct mailservers *np = tp;
  294.     struct tm *ltm;
  295.     time_t t;
  296.     int now;
  297.  
  298. #ifndef UNIX
  299.     if(availmem() - np->reader->stksize < Memthresh){
  300.         /* Memory is tight, don't do anything */
  301.         if (Mailtrace >= 2)
  302.             log(-1,"%s tick exit -- low memory",
  303.                 np->reader->name);
  304.         start_timer(&np->timer);
  305.         return;
  306.     }
  307. #endif
  308.  
  309.     time(&t);
  310.     ltm = localtime(&t);
  311.     now = ltm->tm_hour * 100 + ltm->tm_min;
  312.     if (np->lowtime < np->hightime) {  /* doesn't cross midnight */
  313.         if (now < np->lowtime || now >= np->hightime) {
  314.             if (Mailtrace >= 2)
  315.                 log(-1,"%s window to '%s' not open",
  316.                     np->reader->name,
  317.                     np->hostname);
  318.             start_timer(&np->timer);
  319.             return;
  320.         }
  321.     } else {
  322.         if (now < np->lowtime && now >= np->hightime) {
  323.             if (Mailtrace >= 2)
  324.                 log(-1,"%s window to '%s' not open",
  325.                     np->reader->name,
  326.                     np->hostname);
  327.             start_timer(&np->timer);
  328.             return;
  329.         }
  330.     }
  331.  
  332.     newproc( np->reader->name, np->reader->stksize, np->reader->fp,
  333.         0, tp, NULL,0);
  334. }
  335.  
  336.  
  337. int
  338. mailresponse(s,buf,comment)
  339. int s;          /* Socket index */
  340. char *buf;      /* User buffer */
  341. char *comment;  /* comment for error message */
  342. {
  343.     if (recvline(s,buf,RLINELEN) != -1) {
  344.         if ( Mailtrace >= 3 ) {
  345.             rip(buf);
  346.             log(s,"%s <== %s", comment, buf);
  347.         }
  348.         return 0;
  349.     }
  350.     if ( Mailtrace >= 2 )
  351.         log(s,"receive error for %s response", comment);
  352.     return -1;
  353. }
  354.  
  355.  
  356. /* Check to see if mailbox is already busy (or perpetually locked) */
  357. int
  358. mailbusy( np )
  359. struct mailservers *np;
  360. {
  361.     int countdown = 10;
  362.  
  363.     while ( mlock( Mailspool, np->mailbox ) ) {
  364.         if ( --countdown > 0 ) {
  365.             pause( 60000L ); /* 60 seconds */
  366.         } else {
  367.             start_timer(&np->timer);
  368.             return TRUE;
  369.         }
  370.     }
  371.  
  372.     /* release while processing */
  373.     rmlock( Mailspool, np->mailbox );
  374.     return FALSE;
  375. }
  376.  
  377. #endif
  378.